package com.tongji.housediy.view.components
{
	import com.tongji.housediy.events.commonEvent.CursorBitmapEvent;
	import com.tongji.housediy.events.commonEvent.MouseEnabledAdminEvent;
	import com.tongji.housediy.events.commonEvent.RoomNameAdminEvent;
	import com.tongji.housediy.events.commonEvent.RotationRelatedEvent;
	import com.tongji.housediy.events.commonEvent.RulerAdminEvent;
	import com.tongji.housediy.events.commonEvent.ShowHideTitleWindowEvent;
	import com.tongji.housediy.utils.AbsorptionDetection;
	import com.tongji.housediy.utils.DragDropManager;
	import com.tongji.housediy.utils.LoadAdmin;
	import com.tongji.housediy.utils.MathCalculation;
	import com.tongji.housediy.vo.Goods;
	import com.tongji.housediy.vo.PicModel;
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	
	import mx.controls.Alert;
	import mx.core.UIComponent;
	import mx.events.CloseEvent;
	import mx.events.DragEvent;
	import mx.managers.DragManager;
	
	import spark.filters.DropShadowFilter;
	
	/**
	 * 
	 * @author chenchao
	 * 
	 */
	public class AbstractBorderChild extends RoomShape
	{
		private var _typeIndex:int;
		
		public function get typeIndex():int
		{
			return _typeIndex;
		}

		public function set typeIndex(value:int):void
		{
			_typeIndex = value;
		}

		private var _dragType:String;
		
		public function get dragType():String
		{
			return _dragType;
		}

		public function set dragType(value:String):void
		{
			_dragType = value;
		}
		
		private var _parentBorder:RoomBorder;

		public function get parentBorder():RoomBorder
		{
			return _parentBorder;
		}

		public function set parentBorder(value:RoomBorder):void
		{
			_parentBorder = value;
		}
		
		private var _length:Number;

		public function get length():Number
		{
			return _length;
		}

		public function set length(value:Number):void
		{
			_length = value;
		}
		
		protected var firstVertex:Sprite;
		protected var secondVertex:Sprite;
		protected var currentVertex:Sprite;
		
		private var _percentPosition:Number;
		
		public function get percentPosition():Number
		{
			return _percentPosition;
		}
		
		public function set percentPosition(value:Number):void
		{
			_percentPosition = value;
		}
		
		public var rotationBtnX:Number;
		public var rotationBtnY:Number;
		
		public var rotateState:int;
		public var segFlag:Boolean;
		
		public var initialData:Vector.<Number>;
		
		public var map:BitmapData;
		
		private var tempPicModel:PicModel;
		
		// 临时变量，用于碰撞后还原
		private var tempData0:Number;
		private var tempData1:Number;
		private var tempData2:Number;
		private var tempData3:Number;
		private var tempMap:BitmapData;
		private var tempLength:Number;
		
		///////////////////////by zazisb 该孩子是否被共享
		public var borrowed:Boolean;
		public var shared:Boolean;
		public var fake:Boolean;
		public var sharedBorder:RoomBorder;
		///////////////////////////////////////////////
		
		public function AbstractBorderChild(length:Number = 0, hostGoods:Goods = null, map:BitmapData = null)
		{
			super();
			
			if (length > 0)
				this.length = length;
			if (hostGoods)
			{
				this.hostGoods = hostGoods;
				this.selectedColorID = hostGoods.selectedColorID;
				this.selectedSizeID = hostGoods.selectedSizeID;
			}
			if (map)
				this.map = map;
			
			if (this.dragType == "openingFormat")
			{
				firstVertex = new Sprite();
				drawVertex(firstVertex, 0);
				
				secondVertex = new Sprite();
				drawVertex(secondVertex, 1);
			}
			
			segFlag = false;
			rotateState = 1;
			
			///////////////////////by zazisb 该孩子是否被共享
			borrowed = false;
			shared = false;
			fake = false;
			///////////////////////////////////////////////
		}
		
		public function setRotation(data:Vector.<Number>, k:Number, pedalPoint:Point):void
		{
			if (data[data.length - 1] < data[1])
				this.rotation = -Math.atan((data[data.length - 2] - data[0]) / (data[data.length - 1] - data[1])) * 180 / Math.PI - 180;
			else
				this.rotation = -Math.atan((data[data.length - 2] - data[0]) / (data[data.length - 1] - data[1])) * 180 / Math.PI;
			
			this.data[0] = pedalPoint.x;
			this.data[1] = pedalPoint.y;
			var point:Point = MathCalculation.getOffsetValue(k, length, data);
			this.data[2] = pedalPoint.x + point.x;
			this.data[3] = pedalPoint.y + point.y;
			
			calculateRotateBtn(this.data, k);
		}
		
		public function addFilter():void
		{
			this.filters = [new GlowFilter()];
		}
		
		public function removeFilter():void
		{
			this.filters = [];
		}
		
		override protected function mouseOverHandler(event:MouseEvent):void
		{
			super.mouseOverHandler(event);
			event.stopImmediatePropagation();
		}
		
		override protected function mouseOutHandler(event:MouseEvent):void
		{
			super.mouseOutHandler(event);
			event.stopImmediatePropagation();
		}
		
		override protected function mouseDownHandler(event:MouseEvent):void
		{
			if (this.parentBorder)
			{
				// 隐藏 RotaionBtn
				this.dispatchEvent(new RotationRelatedEvent(RotationRelatedEvent.HIDE_ROTATION_BTN));
				
				// 隐藏 InfoWindow
				this.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW));
				
				// 隐藏 RoomName
				this.dispatchEvent(new RoomNameAdminEvent(RoomNameAdminEvent.HIDE_ROOM_NAME));
				
				this.parentBorder.addEventListener(DragEvent.DRAG_COMPLETE, dragCompleteHandler);
				///////////////////////////////by zazisb
				if(this is OpeningWall)
					AbsorptionDetection.DeleteRelateOpenWall(this as OpeningWall);
				
				DragDropManager.startDragBorderChild(this.parentBorder, event, this.dragType, this.clone());
				
				this.parentBorder.dragRemoveChild(this);
				
				event.stopImmediatePropagation();
			}
		}
		
		public function clone():AbstractBorderChild
		{
			return null;
		}
		
		override public function changeSizeAndColor(picModel:PicModel, bitmapData:BitmapData = null, hostGoods:Goods = null):void
		{
			this.tempPicModel = picModel;
			
			var loader:Loader = LoadAdmin.loadBitmapData(picModel.dragPicSrc);
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
		}
		
		private function loadCompleteHandler(event:Event):void
		{
			event.target.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			
			// 保存临时变量
			tempData0 = data[0];
			tempData1 = data[1];
			tempData2 = data[2];
			tempData3 = data[3];
			tempMap = map;
			tempLength = this.length;
			
			// 赋新值
			map = event.target.content.bitmapData;
			this.length = this.map.width;
			
			data[0] = 0;
			data[1] = 0;
			data[2] = 0;
			data[3] = this.length;
			draw();
			
			var point:Point = MathCalculation.calculateOffsetPoint(new Point(0, this.length), this.rotation);
			data[0] = tempData0;
			data[1] = tempData1;
			data[2] = data[0] + point.x;
			data[3] = data[1] + point.y;
			
			if ((this.parent as RoomBorder).isCollisionWithOthers(this))
				Alert.show("发生碰撞或者出界，请重试！", "警告", Alert.OK, this.stage as Sprite, retrieveHandler);
			else
			{
				this.selectedSizeID = tempPicModel.selectedSizeID;
				this.selectedColorID = tempPicModel.selectedColorID;
			}
		}
		
		private function retrieveHandler(event:CloseEvent):void
		{
			(this.parent as RoomBorder).clearAllChildFilter();
			
			data[0] = 0;
			data[1] = 0;
			data[2] = 0;
			data[3] = this.tempLength;
			draw();
			
			data[0] = tempData0;
			data[1] = tempData1;
			data[2] = tempData2;
			data[3] = tempData3;
			this.map = tempMap;
			this.length = tempLength;
		}
		
		private function dragCompleteHandler(event:DragEvent):void
		{
			this.parentBorder.removeEventListener(DragEvent.DRAG_COMPLETE, dragCompleteHandler);
			
			if (event.action == DragManager.NONE)
			{
				this.parentBorder.dragAddChild(this);
				
				///////////////////////////////by zazisb
				AbsorptionDetection.DoAbsorption(this.parentBorder, true, this);
				// 显示 RotaionBtn
				if (this is NormalDoor)
				{
					showRotationBtn();
				}
				
				// 显示 TitleWindow
				dispatchShowInfoEvent();
			}
			else
			{
				this.parentBorder = this.parent as RoomBorder;
			}
			
		}

		public function showRotationBtn():void
		{
			var initialX:Number;
			var initialY:Number;
			
			this.updateBoundingAndCenterPoint();
			//caddy rotateState =1,2,3,4 分别是什么意思？
			if(this.rotateState == 1 || this.rotateState == 4)
			{
				this.calculateRotateBtn(this.data, ((this.parent) as RoomBorder).k);
			}
			else if(this.rotateState == 2 || this.rotateState == 3)
			{
				this.calculateRotateBtn(this.data, ((this.parent) as RoomBorder).k, false);
			}
			
			initialX = this.rotationBtnX + this.parent.parent.x;
			initialY = this.rotationBtnY + this.parent.parent.y;
			
			this.dispatchEvent(new RotationRelatedEvent(RotationRelatedEvent.SHOW_ROTATION_BTN, initialX, initialY, this));
		}
		
		public function calculateRotateBtn(data:Vector.<Number>, k:Number, inside:Boolean = true):void
		{
			var tmpCenX:Number = (data[0] + data[2]) / 2;
			var tmpCenY:Number = (data[1] + data[3]) / 2;
			var tmpPoint:Point;
			
			if(inside)
				tmpPoint = MathCalculation.getOffsetValue(k, -this.length - 20, data);
			else
				tmpPoint = MathCalculation.getOffsetValue(k, this.length + 20, data);
			
			rotationBtnX = tmpCenX + tmpPoint.y - 11.5;
			rotationBtnY = tmpCenY - tmpPoint.x - 11;
		}
		
		public function getReverseRotation(data:Vector.<Number>, k:Number):Number
		{
			if (data[data.length - 1] < data[1])
				return -(-Math.atan((data[data.length - 2] - data[0]) / (data[data.length - 1] - data[1])) * 180 / Math.PI - 180) / 180 * Math.PI;
			else
				return -(-Math.atan((data[data.length - 2] - data[0]) / (data[data.length - 1] - data[1])) * 180 / Math.PI) / 180 * Math.PI;
		}
		
		private function dispatchShowInfoEvent():void
		{
			var firstPoint:Point = new Point((data[0] + data[2]) / 2 + this.parent.parent.x, (data[1] + data[3]) / 2 + this.parent.parent.y);
			var secondPoint:Point = new Point(firstPoint.x + 100, firstPoint.y - 100);
			var windowPoint:Point = this.parent.parent.parent.localToGlobal(secondPoint);
			
			this.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.SHOW_TITLE_WINDOW,
				firstPoint.x, firstPoint.y,
				secondPoint.x, secondPoint.y,
				windowPoint.x, windowPoint.y,
				this));
			
		}
		
		private function drawVertex(sprite:Sprite, index:int):void
		{
			sprite.graphics.clear();
			sprite.graphics.lineStyle(1, 0x000000);
			sprite.graphics.beginFill(0xffffff);
			sprite.graphics.drawCircle(0, 0, 5);
			sprite.graphics.endFill();
			
			this.addChild(sprite);
			sprite.x = initialData[index * 2];
			sprite.y = initialData[index * 2 + 1];
			sprite.alpha = 0;
			sprite.name = index.toString();
			sprite.visible = false;
			
			sprite.addEventListener(MouseEvent.MOUSE_OVER, vertexMouseOverHandler);
		}
		
		private function vertexMouseOverHandler(event:MouseEvent):void
		{
			if (this.parentBorder)
			{
				if (event.target.name == "0")
					dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.SHOW_CUSTOM_CURSOR,
						this.parent.parent.x + data[0],
						this.parent.parent.y + data[1],
						"center"));
				else
					dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.SHOW_CUSTOM_CURSOR,
						this.parent.parent.x + data[2],
						this.parent.parent.y + data[3],
						"center"));
				
				event.target.removeEventListener(MouseEvent.MOUSE_OVER, vertexMouseOverHandler);
				event.target.addEventListener(MouseEvent.MOUSE_OUT, vertexMouseOutHandler);
				event.target.addEventListener(MouseEvent.MOUSE_DOWN, vertexMouseDownHandler);
				
				event.stopImmediatePropagation();
			}
		}
		
		private function vertexMouseOutHandler(event:MouseEvent):void
		{
			event.target.addEventListener(MouseEvent.MOUSE_OVER, vertexMouseOverHandler);
			dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.HIDE_CUSTOM_CURSOR, 0, 0));
		}
		
		private var tempX:Number;
		private var tempY:Number;
		
		private function vertexMouseDownHandler(event:MouseEvent):void
		{
			////////////////////////////////by zazisb
			AbsorptionDetection.DeleteRelateOpenWall(this as OpeningWall);
			
			currentVertex = event.target as Sprite;
			
			tempX = this.mouseX;
			tempY = this.mouseY;
			
			event.target.removeEventListener(MouseEvent.MOUSE_DOWN, vertexMouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, vertexMouseUpHandler);
			event.target.addEventListener(Event.ENTER_FRAME, vertexEnterFrameHandler);
			event.target.removeEventListener(MouseEvent.MOUSE_OUT, vertexMouseOutHandler);
			
			this.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW));
			
			// 关闭 GridContainer 的 mouseChildren 属性
			this.dispatchEvent(new MouseEnabledAdminEvent(MouseEnabledAdminEvent.MOUSE_ENABLED_CLOSED));
			
			event.stopImmediatePropagation();
		}
		
		private function vertexEnterFrameHandler(event:Event):void
		{
			var offsetX:Number = this.mouseX - tempX;
			var offsetY:Number = this.mouseY - tempY;
			
			//tempX = this.mouseX;
			//tempY = this.mouseY;
			
			var u:Vector3D = new Vector3D(offsetX, offsetY);
			var v:Vector3D = new Vector3D(initialData[2] - initialData[0], initialData[3] - initialData[1]);
			v.scaleBy(u.dotProduct(v) / v.length / v.length);
			
			if (event.target.name == "0")
			{
				initialData[0] += v.x;
				initialData[1] += v.y;
			}
			else
			{
				initialData[2] += v.x;
				initialData[3] += v.y;
			}
			
			event.target.x += v.x;
			event.target.y += v.y;
			
			dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.UPDATE_CUSTOM_CURSOR,
				this.parent.parent.x + this.parent.parent.mouseX,
				this.parent.parent.y + this.parent.parent.mouseY));
			
			var tempPoint:Point = resetProperties();
			var distance:Number = Point.distance(new Point(initialData[0], initialData[1]), new Point(initialData[2], initialData[3]));
			var index:int = this.parentBorder.getChildIndex(this);
			if (distance < 50
				|| Point.distance(new Point(this.parentBorder.data[0], this.parentBorder.data[1]), new Point(data[2], data[3])) <= distance
				|| Point.distance(new Point(data[0], data[1]), new Point(this.parentBorder.data[2], this.parentBorder.data[3])) <= distance
				|| (index > 1 && Point.distance(new Point((this.parentBorder.getChildAt(index - 1) as AbstractBorderChild).data[2], (this.parentBorder.getChildAt(index - 1) as AbstractBorderChild).data[3]), new Point(data[2], data[3])) <= distance)
				|| (index < this.parentBorder.numChildren - 1 && Point.distance(new Point((this.parentBorder.getChildAt(index + 1) as AbstractBorderChild).data[0], (this.parentBorder.getChildAt(index + 1) as AbstractBorderChild).data[1]), new Point(data[0], data[1])) <= distance))
			{
				if (event.target.name == "0")
				{
					initialData[0] -= v.x;
					initialData[1] -= v.y;
				}
				else
				{
					initialData[2] -= v.x;
					initialData[3] -= v.y;
				}
				event.target.x -= v.x;
				event.target.y -= v.y;
			}
			else
			{
				tempX = this.mouseX;
				tempY = this.mouseY;
				
				this.parentBorder.showOverInteriorRuler(this, tempPoint);
			}
			
			draw();
		}
		
		private function vertexMouseUpHandler(event:MouseEvent):void
		{
			currentVertex.addEventListener(MouseEvent.MOUSE_DOWN, vertexMouseDownHandler);
			stage.removeEventListener(MouseEvent.MOUSE_UP, vertexMouseUpHandler);
			currentVertex.removeEventListener(Event.ENTER_FRAME, vertexEnterFrameHandler);
			currentVertex.addEventListener(MouseEvent.MOUSE_OUT, vertexMouseOutHandler);
			
			dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.HIDE_CUSTOM_CURSOR, 0, 0));
			dispatchEvent(new RulerAdminEvent(RulerAdminEvent.HIDE_ALL_RULERS));
			
			// 重置 length
			this.length = Point.distance(new Point(initialData[0], initialData[1]), new Point(initialData[2], initialData[3]));
			
			// 重置 x,y
			var offsetPoint:Point = MathCalculation.calculateOffsetPoint(new Point(initialData[0], initialData[1]), this.rotation);
			this.x += offsetPoint.x;
			this.y += offsetPoint.y;
			
			// 重置 data
			var point:Point = MathCalculation.getOffsetValue(this.parentBorder.k, length, data);
			this.data[0] = this.x;
			this.data[1] = this.y;
			this.data[2] = this.x + point.x;
			this.data[3] = this.y + point.y;
			
			// 重置 firstVertex 和 secondVertex 的位置
			firstVertex.x = 0;
			firstVertex.y = 0;
			secondVertex.x = 0;
			secondVertex.y = length;
			
			// 重置 initialData
			initialData[2] -= initialData[0];
			initialData[3] -= initialData[1];
			initialData[0] = 0;
			initialData[1] = 0;
			
			// 重置 percentPosition
			this.percentPosition = Point.distance(new Point(this.parentBorder.data[0], this.parentBorder.data[1]), new Point(data[0], data[1]))
				/ Point.distance(new Point(this.parentBorder.data[0], this.parentBorder.data[1]), new Point(this.parentBorder.data[2], this.parentBorder.data[3]));
			
			// 开启 GridContainer 的 mouseChildren 属性
			this.dispatchEvent(new MouseEnabledAdminEvent(MouseEnabledAdminEvent.MOUSE_ENABLED_OPENED));
			
			// 重绘
			draw();
			////////////////////////////////by zazisb
			AbsorptionDetection.DoAbsorption(this.parentBorder, true, this);
		}
		
		private function resetProperties():Point
		{
			// 重置 length
			var temp:Number = Point.distance(new Point(initialData[0], initialData[1]), new Point(initialData[2], initialData[3]));
			
			// 重置 x,y
			var offsetPoint:Point = MathCalculation.calculateOffsetPoint(new Point(initialData[0], initialData[1]), this.rotation);
			var tempX:Number = this.x + offsetPoint.x;
			var tempY:Number = this.y + offsetPoint.y;
			
			// 重置 data
			var point:Point = MathCalculation.getOffsetValue(this.parentBorder.k, temp, data);
			this.data[0] = tempX;
			this.data[1] = tempY;
			this.data[2] = tempX + point.x;
			this.data[3] = tempY + point.y;
			
			return new Point(tempX, tempY);
		}
		
		////////////////////////////////////////by zazisb 把转换门状态的函数从mathcalculation移到此处
		public function transformNormalDoorState(segPoint:Point, rotate:Number = 0, state:int = 1, flag:Boolean = false):void 
		{
			var m:Matrix = this.transform.matrix;
			
			m.rotate(rotate);
			switch(state)
			{
				case 1:
					m.a = 1;
					m.d = 1;
					break;
				case 2:
					m.a = -1;
					m.d = 1;
					break;
				case 3:
					m.a = -1;
					m.d = -1;
					break;
				case 4:
					m.a = 1;
					m.d = -1;
					break;	
			}
			m.rotate(-rotate);
			
			switch(state)
			{
				case 1:
				case 2:		
					if (flag)
						m.translate(-segPoint.x, -segPoint.y)
					break;
				case 3:
				case 4:
					if (!flag)
						m.translate(segPoint.x, segPoint.y);
					break;
			}
			
			this.transform.matrix = m;
		}
		///////////////////////////////////////////////////////
	}
}